﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using TrackSystem.Contracts;
using TrackSystem.Entities.DataShaping;
using TrackSystem.Entities.Dtos.Channel;
using TrackSystem.Entities.Models;
using TrackSystem.Entities.RequestFeatures;

namespace TrackSystem.API.Controllers
{
    /// <summary>
    /// 通信通道控制器
    /// </summary>
    [Route("api/channel")]
    [ApiController]
    public class ChannelController : ControllerBase
    {
        private readonly IRepositoryWrapper wrapper;
        private readonly ILogger<ChannelController> logger;
        private readonly IMapper Mapper;

        /// <summary>
        /// 通道控制器构造函数
        /// </summary>
        /// <param name="wrapper"></param>
        /// <param name="logger"></param>
        /// <param name="mapper"></param>
        public ChannelController(IRepositoryWrapper wrapper,
            ILogger<ChannelController> logger,
            IMapper mapper)
        {
            this.wrapper = wrapper;
            this.logger = logger;
            Mapper = mapper;
        }

        /// <summary>
        /// 获取所有通道信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("all")]
        public async Task<IActionResult> GetAll()
        {
            try
            {
                var result = await wrapper.Channel.GetAllListAsync();
                var chns = Mapper.Map<IEnumerable<ChannelDto>>(result);

                return Ok(chns);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[通道设置] 获取异常");
            }
        }

        /// <summary>
        /// 获取所有通道信息，包括传感器信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("all/sensor")]
        public async Task<IActionResult> GetAllWithSensor()
        {
            try
            {
                var result = await wrapper.Channel.GetAllListWithSensorAsync();
                var chns = Mapper.Map<IEnumerable<ChannelWithSensorsDto>>(result);
                return Ok(chns);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[通道设置] 获取异常");
            }
        }

        /// <summary>
        /// 获取分页通道信息
        /// </summary>
        /// <param name="parameter">分页参数</param>
        /// <returns></returns>
        [HttpGet("paged")]
        public async Task<IActionResult> GetPaged([FromQuery] RequestParameter parameter)
        {
            try
            {
                var result = await Task.Run(() => wrapper.Channel.GetPagedChannels(parameter));
                Response.Headers.Append("X-Pagination", Newtonsoft.Json.JsonConvert.SerializeObject(result.MetaData));
                var chns = Mapper.Map<IEnumerable<ChannelDto>>(result).ShapeData(parameter.Fields);

                return Ok(chns);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[通道设置] 获取异常");
            }
        }

        /// <summary>
        /// 根据通道ID获取通道信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}/id", Name = "ChannelById")]
        public async Task<ApiResult<ChannelDto>> GetChannelById(int id)
        {
            try
            {
                var channel = await wrapper.Channel.SingleAsync(a => a.Id == id);
                if (channel == null)
                {
                    string errorMessage = $"通道ID为{id}的通道信息不存在";
                    Response.Headers.Append("ErrorMessage", errorMessage);
                    return ApiResult<ChannelDto>.Fail(errorMessage, StatusCodes.Status204NoContent);
                }
                var channelDto = Mapper.Map<ChannelDto>(channel);
                return ApiResult<ChannelDto>.Ok(channelDto);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道设置] 获取异常");
                return ApiResult<ChannelDto>.Fail(ex.Message, StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// 根据通道名称获取通道信息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet("{name}/name", Name = "ChannelByName")]
        public async Task<IActionResult> GetChannelByName(string name)
        {
            try
            {
                RequestParameter parameter = new RequestParameter
                {
                    Name = name
                };

                var result = await Task.Run(() => wrapper.Channel.GetPagedChannels(parameter)) ;
                Response.Headers.Append("X-Pagination", Newtonsoft.Json.JsonConvert.SerializeObject(result.MetaData));
                var chns = Mapper.Map<IEnumerable<ChannelDto>>(result).ShapeData(parameter.Fields);

                return Ok(chns);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[通道设置] 获取异常");
            }
        }

        /// <summary>
        /// 添加通道信息
        /// </summary>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ApiResult<ChannelDto>> AddChannel(ChannelDto channel)
        {
            try
            {
                var result =  await wrapper.Channel.InsertChannelAsync(channel);
                if (result.Success && result.Data != null)
                {
                    var chnResult =  await wrapper.Var.UpdateBaseChannel(Mapper.Map<ChannelTable>(result.Data));
                    return chnResult.Success ?
                        ApiResult<ChannelDto>.Ok(result.Data) : ApiResult<ChannelDto>.Fail(chnResult.Message ??= "");
                }
                return result;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道添加异常]");
                return ApiResult<ChannelDto>.Fail("通道添加异常", StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// 修改通道信息
        /// </summary>
        /// <param name="channel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<ChannelDto>> UpdateChannel(ChannelDto channel)
        {
            try
            {
                var result = await wrapper.Channel.UpdateChannelAsync(channel);
                if (!result.Success) return result;
                var chnResult = await wrapper.Var.UpdateBaseChannel(Mapper.Map<ChannelTable>(result.Data));
                return chnResult.Success ?
                    ApiResult<ChannelDto>.Ok(channel, "通道添加成功") : ApiResult<ChannelDto>.Fail(chnResult.Message ??= "");
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道更新异常]");
                return ApiResult<ChannelDto>.Fail(ex.Message, StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// 删除通道信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id:int}")]
        public async Task<ApiResult<ChannelDto>> DeleteChannel(int id)
        {
            try
            {
                var channel = await wrapper.Channel.SingleAsync(a => a.Id == id);
                if (channel == null)
                {
                    string errorMessage = $"通道ID为{id}的通道信息不存在";
                    return ApiResult<ChannelDto>.Fail(errorMessage, StatusCodes.Status204NoContent);
                }

                var sensors = wrapper.Sensor.Count(a => a.channelID == id);
                if (sensors > 0)
                {
                    string errorMessage = $"通道ID为{id}的通道信息已被传感器使用，无法删除";
                    return ApiResult<ChannelDto>.Fail(errorMessage, StatusCodes.Status204NoContent);
                }

                var result = await wrapper.Channel.DeleteChannelAsync(id);
                if (result.Success)
                {
                    var chnResult = await wrapper.Var.DeleteBaseChannel(id);
                    return chnResult.Success ?
                        ApiResult<ChannelDto>.Ok(result.Message ??= "") : ApiResult<ChannelDto>.Fail(chnResult.Message ??= "");
                }
                return result;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[通道删除异常]");
                return ApiResult<ChannelDto>.Fail(ex.Message, StatusCodes.Status500InternalServerError);
            }
        }
    }
}
